package org.freez4.spring.data.binding;

import org.freez4.spring.ioc.overview.domain.Company;
import org.freez4.spring.ioc.overview.domain.User;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValues;
import org.springframework.validation.DataBinder;

import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * {@link DataBinder} 示例。
 *
 * @author 阿坤同学
 * @date 2024/2/12 19:58
 */
public class DataBinderDemo {

    private static final Logger logger = Logger.getLogger(DataBinderDemo.class.getName());


    public static void main(String[] args) {
        displayDemo1();
        displayDemo2();
        displayDemo3();
    }

    /**
     * DataBinder 特性1：忽略未知的属性。
     *
     * @author 阿坤同学
     * @date 2024/2/13 15:20
     */

    private static void displayDemo1() {
        // 创建空白对象
        User user = new User();
        // 1. 创建 DataBinder
        DataBinder binder = new DataBinder(user, "");
        // 2. 创建 PropertyValues
        Map<String, Object> source = new HashMap<>();
        source.put("id", 1);
        source.put("name", "阿坤同学");
        source.put("email", "akwangl777@gmail.com");
        PropertyValues propertyValues = new MutablePropertyValues(source);
        // 3. 数据绑定
        binder.bind(propertyValues);
        print(user, binder);
    }

    /**
     * DataBinder 特性2：支持嵌套属性。
     *
     * @author 阿坤同学
     * @date 2024/2/13 15:20
     */

    private static void displayDemo2() {
        // 创建空白对象
        User user = new User();
        // 1. 创建 DataBinder
        DataBinder binder = new DataBinder(user, "");
        // 2. 创建 PropertyValues
        Map<String, Object> source = new HashMap<>();
        source.put("id", 1);
        source.put("name", "阿坤同学");
        source.put("company.name", "free");
        PropertyValues propertyValues = new MutablePropertyValues(source);
        // 3. 数据绑定
        binder.bind(propertyValues);
        print(user, binder);
    }

    /**
     * DataBinder 特性3
     * <pre>
     * 1. 调整 IgnoreUnknownFields true（默认） -> false：忽略未知字段
     * 2. 调整自动增加嵌套路径 true（默认） —> false
     * 3. 调整 ignoreInvalidFields false(默认） -> true（默认情况调整不变化，需要调增 AutoGrowNestedPaths 为 false）
     * 4. 调整必须字段binder.setRequiredFields("id", "name", "age"); 但是不会报错，需要通过binder.getBindingResult()结果来处理
     * </pre>
     *
     * @author 阿坤同学
     * @date 2024/2/13 15:20
     */

    private static void displayDemo3() {
        // 创建空白对象
        User user = new User();
        // 1. 创建 DataBinder
        DataBinder binder = new DataBinder(user, "");
        // 2. 创建 PropertyValues
        Map<String, Object> source = new HashMap<>();
        source.put("id", 1);
        source.put("name", "阿坤同学");
        source.put("company", new Company());
        source.put("company.name", "free");

        PropertyValues propertyValues = new MutablePropertyValues(source);

        // 1. 调整 IgnoreUnknownFields true（默认） -> false（抛出异常，age 字段不存在于 User 类）
        binder.setIgnoreUnknownFields(false);

        // 2. 调整自动增加嵌套路径 true（默认） —> false
        binder.setAutoGrowNestedPaths(false);

        // 3. 调整 ignoreInvalidFields false(默认） -> true（默认情况调整不变化，需要调增 AutoGrowNestedPaths 为 false）
        binder.setIgnoreInvalidFields(true);

        binder.setRequiredFields("id", "name", "age");

        // 3. 数据绑定
        binder.bind(propertyValues);
        print(user, binder);
    }


    private static void print(User user, DataBinder binder) {
        logger.log(Level.INFO, () -> "user info: " + user + "\ndataBinder 结果" + binder.getBindingResult());
    }
}